//
//  SCHttpManager.m
//  Shuaiche
//
//  Created by dangshuai on 2019/4/4.
//  Copyright © 2019 zzs. All rights reserved.
//

#import "SCHttpManager.h"
#import <AFNetworking.h>
#import "SCNetworkStatusConst.h"
#import "Config.h"
@interface SCHttpManager ()
@property (nonatomic, strong) AFHTTPSessionManager *sessionManager;
@end

static NSString *sc_build_url(NSString *path) {
    if ([path hasPrefix:@"https://"]) {
        return path;
    }
    
    if ([path hasPrefix:@"http://"]) {
        return [path stringByReplacingOccurrencesOfString:@"http://" withString:@"https://"];
    }
    
    if ([path hasPrefix:@"/"]) {
        return [NSString stringWithFormat:@"%@%@",kSC_API_DOMAIN,path];
    }
    
    return [NSString stringWithFormat:@"%@/%@",kSC_API_DOMAIN,path];
}

@implementation SCHttpManager

+ (SCHttpManager *)shareInstance {
    static SCHttpManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[SCHttpManager alloc] init];
    });
    return manager;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
#ifdef APP_STORE
        config.timeoutIntervalForRequest = 10;
#else
        config.timeoutIntervalForRequest = 100;
#endif
        
//#ifdef DEBUG
//        config.timeoutIntervalForRequest = 100;
//#else
//        config.timeoutIntervalForRequest = 10;
//#endif
        _sessionManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:config];
        _sessionManager.requestSerializer = [AFJSONRequestSerializer serializer];
        [_sessionManager.requestSerializer setValue:[[NSUserDefaults standardUserDefaults] objectForKey:kSessionId] forHTTPHeaderField:@"user-session-id"];
        
        [_sessionManager.requestSerializer setValue:@"2" forHTTPHeaderField:kSource];
        NSDictionary *dic = [NSBundle mainBundle].infoDictionary;
        NSString *version = dic[@"CFBundleShortVersionString"];
        [_sessionManager.requestSerializer setValue:version forHTTPHeaderField:@"version"];
        [_sessionManager setTaskWillPerformHTTPRedirectionBlock:^NSURLRequest * _Nullable(NSURLSession * _Nonnull session, NSURLSessionTask * _Nonnull task, NSURLResponse * _Nonnull response, NSURLRequest * _Nonnull request) {
            NSMutableURLRequest *mutableRequest = [request mutableCopy];
            mutableRequest.HTTPMethod = task.originalRequest.HTTPMethod;
            mutableRequest.HTTPBody = task.originalRequest.HTTPBody;
            
            NSMutableDictionary *headers = [NSMutableDictionary dictionaryWithDictionary:request.allHTTPHeaderFields];
            mutableRequest.allHTTPHeaderFields = headers;
            if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) {
                [mutableRequest addValue:@"application/json; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
            }
            return mutableRequest;
        }];
    }
    return self;
}

- (void)updateHeaderFieldSession:(id)userSession {
    [_sessionManager.requestSerializer setValue:userSession forHTTPHeaderField:@"user-session-id"];
}

- (NSDictionary *)requestHeader {
    return _sessionManager.requestSerializer.HTTPRequestHeaders;
}

#pragma mark -- 新版本

/**
 * 新版本使用
 * ---GET---
 * @param urlString urlPath
 * @param param     params
 * @param handleBlock   返回的有效数据
 */
- (void)httpGet:(NSString *)urlString param:(NSDictionary *)param completion:(HttpHandleBlock)handleBlock {
    WEAKSELF
  [_sessionManager GET:sc_build_url(urlString) parameters:param headers:nil progress:^(NSProgress * _Nonnull downloadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if ([responseObject isKindOfClass:[NSDictionary class]] || [responseObject isKindOfClass:[NSArray class]]) {
            NSData *body = [task.originalRequest HTTPBody];
            NSString *bodyStr = nil;
            if (body) {
                bodyStr = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding];
            }
            NSString *request = [task.originalRequest.URL absoluteString];
            NSString *response = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding];
            
            LogInfo(@"param = %@, urlString = %@", param, urlString);
            
            NSLog(@"send request:%@, method:%@, httpBody:%@\n responseObject:%@", request, [task.originalRequest HTTPMethod], bodyStr == nil ? @"" : bodyStr,response);
        }
        
        [weakSelf handleResponseSuccess:responseObject withBlock:handleBlock];

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [weakSelf handleResponseFailed:error withBlock:handleBlock];
    }];
}

/**
 * 新版本使用
 * ---POST---
 * @param urlString urlPath
 * @param param     params
 * @param handleBlock   返回的有效数据
 */
- (void)httpPost:(NSString *)urlString param:(NSDictionary *)param completion:(HttpHandleBlock)handleBlock {
    WEAKSELF
    [_sessionManager POST:sc_build_url(urlString) parameters:param headers:nil progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if ([responseObject isKindOfClass:[NSDictionary class]] || [responseObject isKindOfClass:[NSArray class]]) {
            NSData *body = [task.originalRequest HTTPBody];
            NSString *bodyStr = nil;
            if (body) {
                bodyStr = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding];
            }
            NSString *request = [task.originalRequest.URL absoluteString];
            NSString *response = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding];
            
            LogInfo(@"param = %@, urlString = %@", param, urlString);
            
            NSLog(@"send request:%@, method:%@, httpBody:%@\n responseObject:%@", request, [task.originalRequest HTTPMethod], bodyStr == nil ? @"" : bodyStr,response);
        }
        
        [weakSelf handleResponseSuccess:responseObject withBlock:handleBlock];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [weakSelf handleResponseFailed:error withBlock:handleBlock];
    }];
}

/**
 * 新版本使用
 *
 * @param urlString urlPath
 * @param param     params
 * @param q         数据队列
 * @param handleBlock   返回的有效数据
 */
- (void)httpPost:(NSString *)urlString queue:(dispatch_queue_t)q param:(NSDictionary *)param completion:(HttpHandleBlock)handleBlock {
    
    AFHTTPSessionManager *manager = [[SCHttpManager shareInstance].sessionManager copy];
    manager.completionQueue = q;
    WEAKSELF
    [manager POST:sc_build_url(urlString) parameters:param headers:nil progress:nil
          success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [weakSelf handleResponseSuccess:responseObject withBlock:handleBlock];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [weakSelf handleResponseFailed:error withBlock:handleBlock];
    }];
}

- (void)handleResponseSuccess:(id  _Nullable) responseObject withBlock:(HttpHandleBlock)handleBlock {
    if ([responseObject[kCode] integerValue] == 0) {
        if (handleBlock) {
            handleBlock(responseObject[kData],nil);
        }
    } else {
        NSString *reason = responseObject[kMsg] ? responseObject[kMsg] : responseObject[kStatusText];
        if (handleBlock) {
            //                NSInteger code = [responseObject[kCode] integerValue];
            //                2010...接口成功返回，但相关操作失败
            NSDictionary *dic = [NSDictionary dictionaryWithObject:reason forKey:NSLocalizedDescriptionKey];
            NSInteger code = 2010;
            if (responseObject[kCode]) {
                code = [responseObject[kCode] integerValue];
            }
            NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:code userInfo:dic];
            NSLog(@"接口报错信息%@", responseObject);
            handleBlock(nil,error);
        }
        if ([responseObject[kCode]integerValue] == -113) {
            [Config showLoginWhenSessionExpired];
        }
        if ([responseObject[kCode]integerValue] == -996) {
            //TODO
            // 提示升级
            NSString *msg = [NSString stringWithFormat:@"版本过低，需要升级到最新版本"];
            UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"升级提示" message:msg preferredStyle:UIAlertControllerStyleAlert];
            UIAlertAction *otherAction = [UIAlertAction actionWithTitle:@"现在升级" style:UIAlertActionStyleDestructive handler:^(UIAlertAction*action) {
//                [SCSysHelper openAppStore];
            }];
            [alertController addAction:otherAction];
            [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
        }
    }
}

- (void)handleResponseFailed:(NSError *)error withBlock:(HttpHandleBlock)handleBlock {
    if (handleBlock) {
        handleBlock(nil,error);
    }
    NSData *data = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
    if(data){
        NSDictionary *info =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        // -113 登录过期码 
        if([info[kStatusCode] integerValue] == -113){
            [Config showLoginWhenSessionExpired];
        }
    }
}

- (void)httpGetUrlValid:(NSString *)urlString completion:(void(^)(BOOL valid))handleBlock{
    
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    config.timeoutIntervalForRequest = 4.0;
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:config];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    manager.requestSerializer = [AFJSONRequestSerializer serializer];

    [manager GET:urlString parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        handleBlock(true);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (error.code == -1022) {
            handleBlock(true);
        }else{
            handleBlock(false);
        }
        
    }];
    
}

@end
